#include "pch.hpp"
#include "AngelscriptHighlighter.hpp"

using namespace Engine;
using namespace Engine::Edit;




AngelscriptHighlighter::AngelscriptHighlighter(QTextDocument *parent, ErrorModel::const_ptr errors)
	: BasicCodeHighlighter(parent)
	, m_errors(errors)
{
	Rule rule;
	QTextCharFormat fmt;
	QStringList keywords;

	// Primitive data types
	keywords
		<< "\\bvoid\\b" << "\\bbool\\b"
		<< "\\bint8\\b" << "\\bint16\\b" << "\\bint\\b" << "\\bint32\\b" << "\\bint64\\b"
		<< "\\buint8\\b" << "\\buint16\\b" << "\\buint\\b" << "\\buint32\\b" << "\\buint64\\b"
		<< "\\bfloat\\b" << "\\bdouble\\b";
	add(keywords, PrimitiveType);
	keywords.clear();


	// User defined types
	// This is a possible extension point, ALL user registered classes could be added here
	// To achieve this, simply iterate over those classes by using asIScriptEngine...
	keywords
		<< "\\bstring\\b";
	add(keywords, UserType);
	keywords.clear();

	// Special values
	keywords
		<< "\\bnull\\b" << "\\btrue\\b" << "\\bfalse\\b";
	add(keywords, SpecialValue);
	keywords.clear();

	// Class related keywoards
	keywords
		<< "\\benum\\b" << "\\bclass\\b" << "\\binterface\\b"
		<< "\\bsuper\\b" << "\\bthis\\b" << "\\btypedef\\b";
	add(keywords, UserTypeKeywords);
	keywords.clear();

	// operators
	keywords
		<< "\\band\\b" << "\\bor\\b" << "\\bxor\\b" << "\\bcast\\b";
	add(keywords, Operators);
	keywords.clear();


	// Control statements
	keywords
		<< "\\bif\\b" << "\\belse\\b"
		<< "\\bfor\\b" << "\\bwhile\\b" << "\\bdo\\b" << "\\bcontinue\\b"<< "\\breturn\\b" 
		<< "\\bswitch\\b" << "\\bcase\\b" << "\\bbreak\\b" << "\\bdefault\\b";
	add(keywords, Control);
	keywords.clear();

	auto functionFormat = format(FunctionCall);
	rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
	rule.format = functionFormat;
	__super::add(rule);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

AngelscriptHighlighter::~AngelscriptHighlighter()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




QTextCharFormat AngelscriptHighlighter::format(Type type) const
{
	QTextCharFormat fmt = __super::basicFormat(Default);

	switch(type)
	{
	case Control:
	case PrimitiveType:
	case UserTypeKeywords:
		fmt.setForeground(QColor(44, 20, 194));
		break;

	case UserType:
		fmt.setForeground(QColor(60, 54, 204));
		break;

	case SpecialValue:
		fmt.setFontItalic(true);
		break;

	case Operators:
	case FunctionCall:
		fmt.setForeground(QColor(116, 48, 59));
		break;

	default:
		throw invalid_value_exception(type);
	}

	return fmt;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void AngelscriptHighlighter::add(QStringList keywords, Type type)
{
	Rule rule;
	auto fmt = format(type);

	foreach(QString keyword, keywords)
	{
		rule.pattern = QRegExp(keyword);
		rule.format  = fmt;
		__super::add(rule);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
